﻿using System;
using CoreComponents.DataAccess;
using NHibernate;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Tool.hbm2ddl;
using Configuration = NHibernate.Cfg.Configuration;
using Environment = NHibernate.Cfg.Environment;


namespace Crowler.InMemoryDb
{
    public class InMemoryDatabase:IDisposable
    {
        private static Configuration _configuration;
	    private static ISessionFactory _sessionFactory;
	    protected ISession Session;

        public InMemoryDatabase()
	    {
		    if (_configuration == null)
		    {
		        var configuration = GetNhibernateConfiguration();
		        _configuration = configuration;
                
			    _sessionFactory = _configuration.BuildSessionFactory();
		    }
		    Session = _sessionFactory.OpenSession();
            new SchemaExport(_configuration).Execute(true, true, false, Session.Connection, null);
	    }

        private static Configuration GetNhibernateConfiguration()
        {
            var configuration = new Configuration()
                .SetProperty(Environment.ReleaseConnections, "on_close")
                .SetProperty(Environment.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionProvider,
                             "NHibernate.Connection.DriverConnectionProvider")
                .SetProperty(Environment.Isolation, "ReadCommitted")
                .SetProperty(Environment.ConnectionString, "Data Source=:memory:;Version=3;New=True;")
                .SetProperty(Environment.ShowSql, "True")
                .SetProperty(Environment.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName);
                foreach (var assembly in SolutionAssemblies.GetAssemblies())
                {
                    configuration.AddAssembly(assembly);
                }
            return configuration;
        }


        public void Dispose()
	    {
		    Session.Dispose();
	    }
    }
}
